package com.foreveross.crawl.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Map;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;

import com.foreveross.crawl.adapter.AbstractAdapter;
import com.google.common.collect.Maps;

/**
 * 本地测试读写参数和文件，方便对比参数和查看结果
 * @author stub
 *
 */
public class FileUtil {
	
	//一个读地址，一个写地址，一个写参数的地址，都是本地自己新建的文本文档
	public static final  String readPath  = "C:/Users/stub/Desktop/test.txt";
	public static final String writePath  =  "C:/Users/stub/Desktop/test1.txt";
	public static final String writeFilterParamPath  =  "C:/Users/stub/Desktop/test2.txt";
	
	/**
	 * 读文件中的参数作为map参数，方便增减
	 * 参数格式 key=value
	 * @return
	 * @throws Exception
	 */
	public static Map<String,String> readParams() throws Exception{
		return readParams(readPath);
	}
	
	/**
	 * 读取文件中的参数作为Map
	 * 参数格式 key=value
	 * @param filePath 文件地址
	 * @return
	 * @throws Exception
	 */
	public static Map<String,String> readParams(String filePath) throws Exception{
		Map<String,String> tMap = getInstanceMap();
		BufferedReader reader = new BufferedReader(new FileReader(new File(filePath)));
		String s;
		while((s=reader.readLine()) != null){
			String[] arr = s.split("=",2);
			tMap.put(arr[0], arr[1]);
		}
		reader.close();
		return tMap;
	}
	
	/**
	 * 把文本中的参数写成params.put(key,value)的格式，省得一个个填
	 * @throws Exception 
	 */
	public static void writeAsParams() throws Exception{
			Map<String,String> params = readParams();
			BufferedWriter writer = new BufferedWriter(new FileWriter(writePath));
			for(String key : params.keySet()){
				String s = String.format("params.put(\"%s\",\"%s\");", key,params.get(key));
				writer.write(s);
				writer.write("\n");
			}
			writer.flush();
			writer.close();
	}
	
	/**
	 * 写出两个map参数的差异到文件中，以便比较直观的看出参数的区别
	 * 常用于自己本地构造的参数和网页直接复制的参数作比较，看区别
	 * @param map 
	 * @param orderMap
	 * @throws Exception
	 */
	public static void writeTwoMapsDiff(Map<String,String> map,Map<String,String> orderMap) throws Exception{
		BufferedWriter writer = new BufferedWriter(new FileWriter(new File(writePath)));
		Map<String, String> tempMap = getInstanceMap();
		writer.write("相同");
		writer.write("\n");
		for(String key : map.keySet()){
			if(orderMap.containsKey(key)){
				if(map.get(key).equals(orderMap.get(key))){
					writer.write("\t" + key + "=" + map.get(key) + "/" + orderMap.get(key));
				}else{
					writer.write( key + "=" + map.get(key) + "/" + orderMap.get(key));
				}
				writer.write("\n");
			}else{
				tempMap.put(key, map.get(key));
			}
		}
		writer.write("第一个");
		writer.write("\n");
		for(String key : tempMap.keySet()){
			writer.write("\t" + key + "=" + tempMap.get(key));
			writer.write("\n");
		}
		writer.write("第二个");
		writer.write("\n");
		for(String key : orderMap.keySet()){
			if(!map.containsKey(key)){
				writer.write("\t" + key + "=" + orderMap.get(key));
				writer.write("\n");
			}
		}
		writer.flush();
		writer.close();
	}
	
	/**
	 * 写字符串到文件，带编码格式
	 * @param src
	 * @param charset
	 * @throws Exception
	 */
	public static void writeStringWithCharset(String src,String charset) throws Exception{
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(writePath), charset);
		writer.write(src);
		writer.flush();
		writer.close();
	}
	
	/**
	 * 写字符串到文件
	 * @param src 字符串
	 * @throws Exception
	 */
	public static void writeString (String src) throws Exception{
		writeString(src, false);
	}
	
	/**
	 * 写字符串到文件
	 * @param src字符串
	 * @param paramBoolean 是否接着写
	 * @throws Exception
	 */
	public static void writeString(String src,boolean paramBoolean) throws Exception{
		writeString(src, paramBoolean, writePath);
	}
	
	public static void writeString(String src,String path) throws Exception{
		writeString(src, false, path);
	}
	
	/**
	 * 写字符串到文件
	 * @param src 字符串
	 * @param paramBoolean 是否清除原来的内容
	 * @param path 文件地址
	 * @throws Exception
	 */
	public static void writeString(String src,boolean paramBoolean,String path) throws Exception{
		BufferedWriter writer = new BufferedWriter(new FileWriter(new File(path),paramBoolean));
		writer.write(src);
		writer.flush();
		writer.close();
	}
	
	/**
	 * 写map参数到文件
	 * 写的格式 key=value
	 * @param map
	 * @throws IOException
	 */
	public static void writeMap(Map<String,String> map) throws IOException{
		BufferedWriter writer = new BufferedWriter(new FileWriter(new File(writeFilterParamPath),true));
		for(String key : map.keySet()){
			writer.write(key + "=" + map.get(key));
		    writer.write("\n");
		}
		writer.flush();
		writer.close();
	}
	
	/**
	 * @deprecated 一般网页有的参数直接复制上去，这个没啥用
	 * 筛选参数
	 * @param fullParams
	 * @param url
	 * @param isGetMethod
	 * @param adapter
	 * @return
	 * @throws Exception
	 */
	public static Map<String,String> filterParams(Map<String,String> fullParams,String url,boolean isGetMethod,AbstractAdapter adapter) throws Exception{
		HttpClient h = adapter.getHttpClient();
		HttpRequestBase r;
		String page;
		r = getRequest(url, fullParams, isGetMethod, adapter);
		page = adapter.excuteRequest(h, r, true);
		
		Map<String,String> tempMap = getInstanceMap();
		String tempPage;
		tempMap.putAll(fullParams);
		for(String key : fullParams.keySet()){
			tempMap.remove(key);
			r = getRequest(url, tempMap, isGetMethod, adapter);
			try{
				tempPage = adapter.excuteRequest(h, r, true);
			}catch(Exception e){
				tempMap.put(key, fullParams.get(key));
				System.out.println("need key:" + key + "exception");
				continue;
			}
			if(page.length() - tempPage.length() > 1000){
				tempMap.put(key, fullParams.get(key));
				System.out.println("need key:" + key);
			}else{
				System.out.println("remove key:" + key);
			}
		}
		return tempMap;
	}
	
	/**
	 * @deprecated
	 * @param url
	 * @param params
	 * @param isGetMethod
	 * @param adapter
	 * @return
	 * @throws Exception
	 */
	private static HttpRequestBase getRequest(String url,Map<String,String> params,boolean isGetMethod,AbstractAdapter adapter) throws Exception{
		if(isGetMethod){
			return adapter.getBaseGet(url, params);
		}else{
			return adapter.getBasePost(url, params);
		}
	}
	
	/**
	 * 获取一个实例Map类型
	 * @return
	 */
	private static <K,V> Map<K,V> getInstanceMap(){
		return Maps.newLinkedHashMap();
	}
	
	public static void main(String[] args) throws Exception {
		writeTwoMapsDiff(readParams(), readParams(writeFilterParamPath));
	}
}
